part of 'data_mng.dart';

typedef Data = List<int>;

///指令发送debounce防抖间隔
final kMsgInterval = Duration(milliseconds: 80);

///音源
enum AudioSource { HiLevel, LowLevel, BT, USB, Optic, Aux }

extension DataSend on Data {
  ///写入蓝牙数据
  void send() {
    BleHelper.write(this);
  }

  ///填充14字节
  Data fill({bool addHeader = false}) {
    if (length < 2) return this;
    if (this[0] != 0xaa || addHeader) {
      //填充头
      insertAll(0, [0xaa, 0x55]);
    }
    while (length < 14) {
      add(0x00);
    }
    return this;
  }
}

extension Msg on DataMng {
  ///设置音源
  static Data msgAudioSource(AudioSource audioSource) {
    final datas = [
      [0xaa, 0x82, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x4e, 0x7d, 0x55],
      [0xaa, 0x82, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x4d, 0x7d, 0x55],
      [0xaa, 0x82, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x4d, 0x7d, 0x55]
    ];
    var si = [AudioSource.HiLevel, AudioSource.BT, AudioSource.Aux];
    var i = si.indexOf(audioSource);
    return datas[i];
  }

  ///重置均衡
  ///0xFF,0x02,0xc0~0xc6(0xc0全部)
  static void msgResetEQ() {
    [0xFF, 0x02, 0xc0].fill().send();
  }

  ///重置xover
  ///0x33, 0x44, 0x00
  static void msgResetXover() {
    [0x33, 0x44, 0x00].fill().send();
  }

  ///重置dsp(全部数据)
  static void msgResetDsp() {
    [0xaa, 0xff, 0xff].fill(addHeader: true).send();

    List<int> data = [];
    var filter = utf8.encode('resetfilter');
    data.addAll(filter.sublist(0, 5));
    data.add(0xca);
    data.addAll(filter.sublist(6));
    data.addAll([0x55, 0xaa]);
    data.fill().send();
  }

  ///延时
  static Data msgDelay(int ch, int delay, {bool active = false}) {
    var msg = ZFDelayMsg()
      ..delay.value = active ? delay : 0
      ..ch.value = ch + 0xc1;
    return msg.data();
  }

  ///下发所有delay、gain数据
  static void msgDelayGainSendAllChsData() {
    var model = DataMng.shared.advancedModel;
    var timeDelay = model.timeDelay;
    var levelModel = model.level;
    for (int i = 0; i < kChCount; i++) {
      Msg.msgDelay(i, (timeDelay.timeDelays[i] * 100).toInt());

      var volume = -levelModel.items[i].volume * kVolumeRadio;
      Msg.msgVolume(i, volume);
    }
  }

  ///0x52, 0x45, 0x4d, 0x53, 0x45, 0x54
  ///0xaa55
  ///5245  4d53    4554    008c00000000
  ///ZFSummingDelayMsg
  static void msgSummingDelay(int delay) {
    int b0 = (delay & 0xff00) >> 8;
    int b1 = delay & 0x00ff;
    [0x52, 0x45, 0x4d, 0x53, 0x45, 0x54, b0, b1].fill().send();
  }

  ///音量
  static Data msgVolume(int ch, int volume, {bool mute = false}) {
    var msg = ZFVolumeMsg()
      ..volume.value = volume
      ..mute.value = mute.toInt()
      ..ch.value = ch + 0xc1;
    return msg.data();
  }

  ///发送总音量
  ///0xEE, 是/否静音(0x00否,0x01是), dB音量(0x0000~0x03B6)
  static Data msgVolumeTotal(int volume, {bool mute = false}) {
    var msg = ZFTotalVolumeMsg()
      ..volume.value = volume
      ..mute.value = mute.toInt();
    return msg.data();
  }

  ///反相
  static Data msgParaphase(int ch, int paraphase, {bool active = false}) {
    ZFParaphaseMsg msg = ZFParaphaseMsg();
    msg.ch.value = 0xc1 + ch;
    msg.paraphase.value = active ? paraphase : 0;
    return msg.data();
  }

  ///下发xover所有通道数据
  static void msgXoverSendAllChsData() {
    for (int i = 0; i < DataMng.shared.xoverModel.items.length; i++) {
      msgXover2(selectCH: i, isHigh: true);
      msgXover2(selectCH: i, isHigh: false);
    }
  }

  ///下发指定通道的所有xover数据（包括高低通）
  static void msgXoverSendSingleChAllData({int ch = 0}) {
    msgXover2(selectCH: ch, isHigh: true);
    msgXover2(selectCH: ch, isHigh: false);
  }

  ///下发当前通道Xover数据
  static void msgXover({required bool isHigh}) {
    msgXover2(selectCH: DataMng.shared.xoverModel.selectCH, isHigh: isHigh);
  }

  ///下发Xover数据
  static void msgXover2({required int selectCH, required bool isHigh}) {
    var xoverModel = DataMng.shared.xoverModel;
    var chConfig = xoverModel.chConfig;
    var xoverItemModel = xoverModel.itemModel(selectCH: selectCH);
    XoverItemHighLowModel? xoverItemHighLowModel;
    if (isHigh) {
      //高通
      xoverItemHighLowModel = xoverItemModel.high;
    } else {
      //低通
      xoverItemHighLowModel = xoverItemModel.low;
    }
    int freq = xoverItemHighLowModel.freq;
    if (xoverItemHighLowModel.isBypass) {
      freq = isHigh ? 20 : 20000;
    }

    /*
        EZAMP协议
        //0xDD, 通道(0xC1~0xC6), H类型(0x00 bessel,0x01 btr-w,0x02 link-r),H斜率(0x00 6,0x01 12,0x02 24,0x03 48),H频率(0x0014~0x4E20)
        //0xDE, 通道(0xC1~0xC6), L类型(0x00 bessel,0x01 btr-w,0x02 link-r),L斜率(0x00 6,0x01 12,0x02 24,0x03 48),L频率(0x0014~0x4E20)
        */
    //是否联调
    var chObj = chConfig.chs[selectCH];
    var isGroup = chObj.isGroup;
    var count = isGroup ? 2 : 1; //联调时，连续发两个通道的数据
    for (int i = 0; i < count; i++) {
      var ch = 0xc1 + selectCH;
      if (isGroup) {
        //group
        ch = chConfig.chs[i].index + 0xc1;
      }
      ZFXoverMsg msg = ZFXoverMsg();
      msg.cmd.value = isHigh ? 0xdd : 0xde;
      msg.ch.value = ch;
      msg.type.value = xoverItemHighLowModel.type;
      msg.xielv.value = xoverItemHighLowModel.slope;
      msg.freq.value = freq;

      print("xover $msg");

      msg.data().send();
    }
  }

  ///下发所有通道的EQ数据
  static void msgEqSendAllChsData() {
    for (var i = 0; i < kChCount; i++) {
      for (int j = 0; j < DataMng().eqModel.pdCount; j++) {
        msgEq3(selectCH: i, pd: j, onlyCh: true);
      }
    }
  }

  ///下发当前通道的所有频点的EQ数据
  static void msgEqSendSingleChAllPdsData(int ch) {
    final i = ch;
    for (int j = 0; j < DataMng().eqModel.pdCount; j++) {
      msgEq3(selectCH: i, pd: j, onlyCh: false);
    }
  }

  ///下发当前通道EQ指令
  static void msgEq() {
    msgEq3(
        selectCH: DataMng().eqModel.selectCH,
        pd: DataMng().eqModel.pd,
        onlyCh: false);
  }

  ///发送EQ指令[onlyCh]为false时是发联通指令
  static void msgEq3(
      {required int selectCH, required int pd, required bool onlyCh}) {
    /*
     //发送通道频率、Q值、增益
     //0xAA~0xAB(单通道、联调), 通道(0xC1~0xC6),点(0x00~0x0E),频率(0x0014~0x4E20), Q值(0x0005~0x07D0), 增益(0x0000~0x0190)
     */
    ZFEqMsg msg = ZFEqMsg();

    var eqModel = DataMng().eqModel;
    var eqItemModel = eqModel.getItemModel(selectCH, pd);

    //eqModel.chConfig.isChSelected(ch: selectCH);
    var chObj = eqModel.chConfig.chs[selectCH], isGroup = chObj.isGroup;
    if (!onlyCh && isGroup) {
      msg.cmd.value = 0xab; //联调
      var ch = 0, groupIndex = chObj.groupIndex;
      if (groupIndex == 0) {
        ch = 0xc1;
      } else if (groupIndex == 1) {
        ch = 0xc3;
      } else if (groupIndex == 2) {
        ch = 0xc5;
      } else if (groupIndex == 3) {
        ch = 0xc7;
      }
      msg.ch.value = ch; //通道
    } else {
      msg.cmd.value = 0xaa; //单通道（非联调）
      msg.ch.value = selectCH + 0xc1; //通道
    }
    //频点
    msg.pd.value = pd;
    //频率
    msg.freq.value = eqItemModel.freq;
    //Q值
    msg.q.value = (eqItemModel.q * 100).toInt();
    //增益
    msg.gain.value = ((eqItemModel.ch + 20) * 10).toInt();

    print("频率=${msg.freq.value},Q值=${msg.q.value},增益=${msg.gain.value}");

    msg.data().send();
  }

  ///下发合频数据
  static void msgSumming() {
    for (int i = 0; i < kChCount; i++) {
      msgSummingCH(ch: i);
    }
  }

  ///下发制定通道的合频数据、[ch]通道
  static void msgSummingCH({required int ch}) {
    var selectedCH = ch;
    /*
     0XAA ,0x35
     0xc1, //通道1
     0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x00 //8字节input
     //不足14字节补足
     0XCA ,0x55
     */
//    YBSaveSUMMINGModel *model = [DataMng instance].SUMMINGModel;
    /*unsigned char ch = selectedCH+0xc1;
    unsigned char data[] = {0xAA, 0x35, ch, [self isHightHave:1 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:2 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:3 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:4 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:5 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:6 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:7 selectedCH:selectedCH]?0x01:0x00,[self isHightHave:8 selectedCH:selectedCH]?0x01:0x00,0x00, 0XCA, 0x55};
    NSData *data1 = [[NSData alloc] initWithBytes:data length:sizeof(unsigned char)*14];*/

    ////0xaa,0x83,0xf0,0xc1,0x01,0x01,0x01,0x01,0x01,0x01,0x00(统计选中数量),0x00, 0xff,0x0F,0x7c,0x55    //模拟通道下，输入模式选择之自由选择输入模式，跟BTDSP的输入选择那个一样，但是后面多了一个输入数量统计，比如C1通道有两个输入则这个数量为2

    ZFSummingMsg msg = ZFSummingMsg();
    msg.ch.value = selectedCH + 0xc1;

    int sum = 0;
    for (int i = 1; i < kChCountIn + 1; i++) {
      int state =
          DataMng.shared.summingModel.isHightHave(ch: i, selectedCH: selectedCH)
              ? 0x01
              : 0x00;
      if (i == 1) {
        msg.ch1.value = state;
      } else if (i == 2) {
        msg.ch2.value = state;
      } else if (i == 3) {
        msg.ch3.value = state;
      } else if (i == 4) {
        msg.ch4.value = state;
      } else if (i == 5) {
        msg.ch5.value = state;
      } else if (i == 6) {
        msg.ch6.value = state;
      } else if (i == 7) {
        msg.ch7.value = state;
      } else if (i == 8) {
        msg.ch8.value = state;
      }
      if (state == 0x01) {
        sum++;
      }
    }

    msg.data().send();
  }
}
